home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / MacPerl 5.1.3 / Mac_Perl_513_src / MacPerl5 / MPMain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-21  |  31.3 KB  |  1,456 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPMain.c            -    The main event loop
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPMain.c,v $
  12. Revision 1.2  1994/05/04  02:52:40  neeri
  13. Inline Input.
  14.  
  15. Revision 1.1  1994/02/27  23:01:21  neeri
  16. Initial revision
  17.  
  18. Revision 0.9  1993/12/30  00:00:00  neeri
  19. DeferredKeys
  20.  
  21. Revision 0.8  1993/12/20  00:00:00  neeri
  22. Trying to be more subtle about cursors
  23.  
  24. Revision 0.7  1993/12/12  00:00:00  neeri
  25. SacrificialGoat
  26.  
  27. Revision 0.6  1993/10/17  00:00:00  neeri
  28. Mercutio Support
  29.  
  30. Revision 0.5  1993/08/17  00:00:00  neeri
  31. Preferences
  32.  
  33. Revision 0.4  1993/08/16  00:00:00  neeri
  34. Moved scripting to separate file
  35.  
  36. Revision 0.3  1993/07/15  00:00:00  neeri
  37. Beginning to see the light
  38.  
  39. Revision 0.2  1993/05/30  00:00:00  neeri
  40. Support Console Windows
  41.  
  42. Revision 0.1  1993/05/29  00:00:00  neeri
  43. Compiles correctly
  44.  
  45. *********************************************************************/
  46.  
  47. #include <Memory.h>
  48. #include <QuickDraw.h>
  49. #include <Types.h>
  50. #include <Menus.h>
  51. #include <Windows.h>
  52. #include <Dialogs.h>
  53. #include <Traps.h>
  54. #include <Packages.h>
  55. #include <DiskInit.h>
  56. #include <PPCToolbox.h>
  57. #include <Resources.h>
  58. #ifdef EVIL_USELESS_EDITIONS
  59. #include <Editions.h>
  60. #endif
  61. #include <Printing.h>
  62. #include <ToolUtils.h>
  63. #include <Desk.h>
  64. #include <Scrap.h>
  65. #include <OSEvents.h>
  66. #include <AppleEvents.h>
  67. #include <AEObjects.h>
  68. #include <Errors.h>
  69. #include <StandardFile.h>
  70. #include <Balloons.h>
  71. #include <String.h>
  72. #include <CType.h>
  73. #include <PLStringFuncs.h>
  74. #include <StdLib.h>
  75. #include <CursorCtl.h>
  76. #include <Script.h>
  77. #include <SegLoad.h>
  78. #include <LowMem.h>
  79.  
  80. #include "MPGlobals.h"
  81. #include "MPUtils.h"
  82. #include "MPEditions.h"
  83. #include "MPAppleEvents.h"
  84. #include "MPWindow.h"
  85. #include "MPFile.h"
  86. #include "MPHelp.h"
  87. #include "MPScript.h"
  88. #include "MPUtils.h"
  89. #include "MPPreferences.h"
  90. #include "MercutioAPI.h"
  91. #include "MPConsole.h"
  92. #include "MPPseudoFile.h"
  93. #include "MPEditor.h"
  94.  
  95. #if !defined(powerc) && !defined(__powerc)
  96. #pragma segment MPMain
  97. #endif
  98.  
  99. pascal void MaintainCursor()
  100. {
  101.     Point         pt;
  102.     WindowPtr     wPtr;
  103.     GrafPtr       savePort;
  104.     DPtr          theDoc;
  105.     Boolean        inText = false;
  106.     
  107.     wPtr = FrontWindow();
  108.     if (Ours(wPtr)) {
  109.         theDoc = DPtrFromWindowPtr(wPtr);
  110.         GetPort(&savePort);
  111.         SetPort(wPtr);
  112.         GetMouse(&pt);
  113.         if (gTextServicesImplemented && SetTSMCursor(pt))
  114.             return;
  115.         if (theDoc->theText)
  116.             if (inText = PtInRect(pt, &(**(theDoc->theText)).viewRect))
  117.                 SetCursor(&editCursor);
  118.             else
  119.                 SetCursor(&qd.arrow);
  120.         else
  121.             SetCursor(&qd.arrow);
  122.  
  123.         if (theDoc->theText)
  124.             TEIdle(theDoc->theText);
  125.  
  126.         SetPort(savePort);
  127.     } else if (!wPtr)
  128.         SetCursor(&qd.arrow);
  129. }
  130.  
  131. #if !defined(powerc) && !defined(__powerc)
  132. #pragma segment MPMain
  133. #endif
  134.  
  135. FSSpec        jumpFile;
  136. WindowPtr    jumpWindow;
  137. short            jumpLine;
  138.  
  139. Boolean  SeriousFSSpec(char * name)
  140. {
  141.     CInfoPBRec    info;
  142.     
  143.     if (Path2FSSpec(name, &jumpFile))
  144.         return false;
  145.     if (FSpCatInfo(&jumpFile, &info) 
  146.      || info.dirInfo.ioFlAttrib & 0x10 
  147.     ) {
  148.         if (strchr(name, ':') || !(jumpWindow = AlreadyOpen(&jumpFile, jumpFile.name)))
  149.             return false;
  150.     } else {
  151.         switch (GetDocTypeFromInfo(&info)) {
  152.         case kUnknownDoc:
  153.         case kPreferenceDoc:
  154.             return false;
  155.         }
  156.         jumpWindow = nil;
  157.     }
  158.     
  159.     return true;
  160. }
  161.  
  162. Boolean    ParseJump(DPtr    theDoc)
  163. {
  164.     char        endCh;
  165.     Boolean    result = false;
  166.     TEHandle    te     = theDoc->theText;
  167.     short        len    = (*te)->selEnd - (*te)->selStart;
  168.     char *    text;
  169.     char *   end;
  170.     char *   endFile;
  171.     Str255    jumpText;
  172.     
  173.     if (len <= 0)
  174.         goto fixupMenuItem;
  175.     
  176.     HLock((*te)->hText);
  177.     text = *(*te)->hText + (*te)->selStart;
  178.     end  = text + len;
  179.     endCh= *end;
  180.     *end = 0;
  181.  
  182. rescan:    
  183.     while (isspace(*text))
  184.         ++text;
  185.     
  186.     switch (*text) {
  187.     case 'F':
  188.     case 'f':
  189.         if (toupper(text[1]) == 'I' 
  190.          && toupper(text[2]) == 'L' 
  191.          && toupper(text[3]) == 'E'
  192.          && isspace(text[4])
  193.         ) {
  194.             /* Strip off "File" prefix */
  195.             text += 5;
  196.             
  197.             goto rescan;
  198.         } else
  199.             goto slurp;
  200.     case '\'':
  201.     case '\"':
  202.         if (endFile = strchr(text+1, *text)) {
  203.             *endFile = 0;
  204.             
  205.             if (endFile - text < 1 || !SeriousFSSpec(text+1)) {
  206.                 *endFile = *text;
  207.                 
  208.                 goto repair;
  209.             }
  210.             
  211.             *endFile = *text;
  212.             text = endFile + 1;
  213.             
  214.             break;
  215.         } 
  216.         
  217.         /* Unbalanced quote, skip & fall through */
  218.         ++text;
  219.     default:
  220. slurp:
  221.         /* Break at end of line */
  222.         if (endFile = strchr(text, '\n')) {
  223.             /* Strip trailing whitespace */
  224.             while (endFile > text && isspace(endFile[-1]))
  225.                 --endFile;
  226.                 
  227.             *endFile = 0;
  228.             
  229.             if (endFile - text < 1 || !SeriousFSSpec(text)) {
  230.                 *endFile = '\n';
  231.                 
  232.                 goto repair;
  233.             }
  234.             
  235.             *endFile = '\n';
  236.             text = endFile + 1;
  237.             
  238.             break;
  239.         } 
  240.         
  241.         if (end - text < 1 || !SeriousFSSpec(text))
  242.             goto repair;
  243.         
  244.         text = end;
  245.         break;
  246.     }
  247.     
  248.     /* Try to parse line # */
  249.     
  250.     jumpLine = 0;
  251.     
  252.     while (*text)
  253.         if (isdigit(*text)) {
  254.             while (isdigit(*text))
  255.                 jumpLine = jumpLine * 10 + *text++ - '0';
  256.             
  257.             break;
  258.         } else
  259.             ++text;
  260.     
  261.     result = true;
  262.         
  263. repair:    
  264.     *end = endCh;
  265.     HUnlock((*te)->hText);
  266.  
  267. fixupMenuItem:
  268.     if (result) {
  269.         jumpFile.name[jumpFile.name[0]+1] = 0;
  270.         jumpText[0] = sprintf((char *) jumpText+1, "Jump to \"%s\"", jumpFile.name+1);
  271.         if (jumpLine)
  272.             jumpText[0] += 
  273.                 sprintf((char *) jumpText+jumpText[0]+1, ", Line %d", jumpLine);
  274.         SetMenuItemText(myMenus[editM], emJumpTo, jumpText);
  275.     } else 
  276.         SetMenuItemText(myMenus[editM], emJumpTo, (StringPtr) "\pJump To…");
  277.  
  278.     return result;    
  279. }
  280.  
  281. #if !defined(powerc) && !defined(__powerc)
  282. #pragma segment MPMain
  283. #endif
  284.  
  285. static Boolean    mRunningPerl;
  286.  
  287. pascal void MaintainMenuBar()
  288. {
  289.     if (gRunningPerl != mRunningPerl) {
  290.         if (gRunningPerl) 
  291.             DeleteMenu(perlID);
  292.         else
  293.             InsertMenu(myMenus[perlM], 0);
  294.         
  295.         mRunningPerl = gRunningPerl;
  296.         
  297.         DrawMenuBar();
  298.     }
  299. }
  300.  
  301. void MaintainScriptMenu(WindowPtr win)
  302. {
  303.     DPtr        doc;
  304.     short        origLen;
  305.     Str255    title;
  306.     
  307.     if (mRunningPerl) 
  308.         return;
  309.     
  310.     for (; win; win = GetNextWindow(win)) {
  311.         if (!IsWindowVisible(win) || !Ours(win))
  312.             continue;
  313.         if (!(doc = DPtrFromWindowPtr(win)) || doc->kind != kDocumentWindow)
  314.             continue;
  315.  
  316.         PLstrcpy(title, (StringPtr) "\pRun ");
  317.         origLen                 = title[0];
  318.         GetWTitle(win, title+origLen+1);
  319.         title[0]             = title[origLen+1] + origLen + 2;
  320.         title[origLen+1]    = '"';
  321.         title[title[0]]    = '"';
  322.         SetItem(myMenus[perlM], pmRunFront, title);
  323.         EnableItem(myMenus[perlM], pmRunFront);
  324.         
  325.         PLstrcpy(title, (StringPtr) "\pSyntax Check ");
  326.         origLen                 = title[0];
  327.         GetWTitle(win, title+origLen+1);
  328.         title[0]             = title[origLen+1] + origLen + 2;
  329.         title[origLen+1]    = '"';
  330.         title[title[0]]    = '"';
  331.         SetItem(myMenus[perlM], pmCheckFront, title);
  332.         EnableItem(myMenus[perlM], pmCheckFront);
  333.         
  334.         return;
  335.     }
  336.     
  337.     SetItem(myMenus[perlM], pmRunFront, (StringPtr) "\pRun Front Window");
  338.     DisableItem(myMenus[perlM], pmRunFront);
  339.     SetItem(myMenus[perlM], pmCheckFront, (StringPtr) "\pCheck Front Window");
  340.     DisableItem(myMenus[perlM], pmCheckFront);
  341. }
  342.  
  343. void MaintainEditorMenu(WindowPtr win)
  344. {
  345.     DPtr        doc;
  346.     int        origLen;
  347.     Str255    title;
  348.     
  349.     if (HasExternalEdits())
  350.         EnableItem(myMenus[editorM], xmUpdate);
  351.     else 
  352.         DisableItem(myMenus[editorM], xmUpdate);
  353.  
  354.     PLstrcpy(title, (StringPtr) "\pUpdate ");
  355.     origLen                 = title[0];
  356.     if (GetExternalEditorDocumentName(title+origLen+1)) {
  357.         title[0]             = title[origLen+1] + origLen + 2;
  358.         title[origLen+1]    = '"';
  359.         title[title[0]]    = '"';
  360.         SetItem(myMenus[editorM], xmUpdateFront, title);
  361.         EnableItem(myMenus[editorM], xmUpdateFront);
  362.     } else {
  363.         SetItem(myMenus[editorM], xmUpdateFront, (StringPtr) "\pUpdate");
  364.         DisableItem(myMenus[editorM], xmUpdateFront);
  365.     }
  366.  
  367.     for (; win; win = GetNextWindow(win)) {
  368.         if (!IsWindowVisible(win) || !Ours(win))
  369.             continue;
  370.         if (!(doc = DPtrFromWindowPtr(win)) || doc->kind != kDocumentWindow)
  371.             continue;
  372.  
  373.         PLstrcpy(title, (StringPtr) "\pEdit ");
  374.         origLen                 = title[0];
  375.         GetWTitle(win, title+origLen+1);
  376.         title[0]             = title[origLen+1] + origLen + 2;
  377.         title[origLen+1]    = '"';
  378.         title[title[0]]    = '"';
  379.         SetItem(myMenus[editorM], xmEditFront, title);
  380.         EnableItem(myMenus[editorM], xmEditFront);
  381.         
  382.         return;
  383.     }
  384.     
  385.     SetItem(myMenus[editorM], xmEditFront, "\pEdit Front Window");
  386.     DisableItem(myMenus[editorM], xmEditFront);
  387. }
  388.  
  389. pascal void MaintainMenus()
  390. {
  391.     DPtr               theDoc;
  392.     WindowPtr          firstWindow;
  393. #ifdef EVIL_USELESS_EDITIONS
  394.     SectHandle         currSection;
  395. #endif
  396.  
  397.     MaintainMenuBar();
  398.     
  399.     firstWindow = FrontWindow();
  400.     
  401.     MaintainScriptMenu(firstWindow);
  402.     MaintainEditorMenu(firstWindow);
  403.     
  404.     if (!Ours(firstWindow)) {
  405.         EnableItem(myMenus[fileM], fmNew);
  406.         EnableItem(myMenus[fileM], fmOpen);
  407.         DisableItem(myMenus[fileM], fmClose);
  408.         DisableItem(myMenus[fileM], fmSave);
  409.         DisableItem(myMenus[fileM], fmSaveAs);
  410.         DisableItem(myMenus[fileM], fmRevert);
  411.         DisableItem(myMenus[fileM], fmPrint);
  412.         DisableItem(myMenus[fileM], fmPageSetUp);
  413.         EnableItem(myMenus[fileM], fmQuit);
  414.  
  415.         if (firstWindow) {
  416.             EnableItem(myMenus[editM], undoCommand);
  417.             EnableItem(myMenus[editM], cutCommand);
  418.             EnableItem(myMenus[editM], copyCommand);
  419.             EnableItem(myMenus[editM], pasteCommand);
  420.             EnableItem(myMenus[editM], clearCommand);
  421.         } else {
  422.             DisableItem(myMenus[editM], undoCommand);
  423.             DisableItem(myMenus[editM], cutCommand);
  424.             DisableItem(myMenus[editM], copyCommand);
  425.             DisableItem(myMenus[editM], pasteCommand);
  426.             DisableItem(myMenus[editM], clearCommand);
  427.         }
  428.         EnableItem(myMenus[editM],  emPreferences);
  429.         DisableItem(myMenus[editM], selectAllCommand);
  430.  
  431.         DisableItem(myMenus[editM],  emJumpTo);
  432.         
  433. #ifdef EVIL_USELESS_EDITIONS
  434.         DisableItem(myMenus[editM],  cPublisher);
  435.         DisableItem(myMenus[editM],  cSubscriber);
  436.         DisableItem(myMenus[editM],  cOptions);
  437.         DisableItem(myMenus[editM],  cBorders);
  438. #endif
  439.  
  440.         EnableItem(myMenus[helpM], hmExplain);
  441.     } else {
  442.         theDoc = DPtrFromWindowPtr(firstWindow);
  443.         
  444.         if (theDoc->kind == kDocumentWindow) {
  445.             EnableItem(myMenus[editM], pasteCommand);
  446. #ifdef EVIL_USELESS_EDITIONS
  447.             EnableItem(myMenus[editM], cBorders);
  448. #endif
  449.         } else {
  450. #ifdef EVIL_USELESS_EDITIONS
  451.             DisableItem(myMenus[editM], cBorders);
  452. #endif
  453.  
  454.             if ((*theDoc->theText)->selStart < theDoc->u.cons.fence)
  455.                 DisableItem(myMenus[editM], pasteCommand);
  456.             else
  457.                 EnableItem(myMenus[editM], pasteCommand);
  458.         }
  459.         
  460.         EnableItem(myMenus[fileM], fmClose);
  461.         EnableItem(myMenus[fileM], fmSave);
  462.         EnableItem(myMenus[fileM], fmSaveAs);
  463.         EnableItem(myMenus[fileM], fmPrint);
  464.         EnableItem(myMenus[fileM], fmPageSetUp);
  465.         EnableItem(myMenus[fileM], fmQuit);
  466.  
  467.         if (theDoc->kind == kDocumentWindow && theDoc->u.reg.everSaved && theDoc->dirty)
  468.             EnableItem(myMenus[fileM], fmRevert);
  469.         else
  470.             DisableItem(myMenus[fileM], fmRevert);
  471.  
  472.         DisableItem(myMenus[editM], undoCommand);
  473.  
  474.         if (((**(theDoc->theText)).selEnd - (**(theDoc->theText)).selStart) > 0) {
  475.             EnableItem(myMenus[editM], cutCommand);
  476.             EnableItem(myMenus[editM], copyCommand);
  477.             EnableItem(myMenus[editM], clearCommand);
  478. #ifdef EVIL_USELESS_EDITIONS
  479.             EnableItem(myMenus[editM], cPublisher);
  480. #endif
  481.         } else {
  482.             DisableItem(myMenus[editM], cutCommand);
  483.             DisableItem(myMenus[editM], copyCommand);
  484.             DisableItem(myMenus[editM], clearCommand);
  485. #ifdef EVIL_USELESS_EDITIONS
  486.             DisableItem(myMenus[editM], cPublisher);
  487. #endif
  488.         }
  489.         
  490.         EnableItem(myMenus[editM],  selectAllCommand);
  491.         EnableItem(myMenus[editM],  emPreferences);
  492.  
  493.         if (ParseJump(theDoc))
  494.             EnableItem(myMenus[editM],  emJumpTo);
  495.         else
  496.             DisableItem(myMenus[editM],  emJumpTo);
  497.  
  498. #ifdef EVIL_USELESS_EDITIONS
  499.         currSection =
  500.             GetSection(
  501.                 (**(theDoc->theText)).selStart,
  502.                 (**(theDoc->theText)).selEnd,
  503.                 theDoc);
  504.  
  505.         if (theDoc->kind != kDocumentWindow) {
  506.             DisableItem(myMenus[editM], cPublisher);
  507.             DisableItem(myMenus[editM], cSubscriber);
  508.             DisableItem(myMenus[editM], cOptions);
  509.         } else if (currSection) {
  510.             DisableItem(myMenus[editM], cPublisher);
  511.             DisableItem(myMenus[editM], cSubscriber);
  512.             EnableItem(myMenus[editM],  cOptions);
  513.             if ((**(**currSection).fSectHandle).kind == stPublisher)
  514.                 SetItem(myMenus[editM], cOptions, (StringPtr) "\pPublisher Options…");
  515.             else
  516.                 SetItem(myMenus[editM], cOptions, (StringPtr) "\pSubscriber Options…");
  517.         } else {
  518.             EnableItem(myMenus[editM],  cPublisher);
  519.             EnableItem(myMenus[editM],  cSubscriber);
  520.             DisableItem(myMenus[editM], cOptions);
  521.         }
  522. #endif
  523.  
  524.         EnableItem(myMenus[helpM], hmExplain);
  525.     }
  526. }
  527.  
  528. #if !defined(powerc) && !defined(__powerc)
  529. #pragma segment MPMain
  530. #endif
  531.  
  532. pascal void SetUpCursors(void)
  533. {
  534.     CursHandle  hCurs;
  535.  
  536.     hCurs = GetCursor(1);
  537.     editCursor = **hCurs;
  538.     hCurs = GetCursor(watchCursor);
  539.     waitCursor = **hCurs;
  540. }
  541.  
  542. #if !defined(powerc) && !defined(__powerc)
  543. #pragma segment MPMain
  544. #endif
  545.  
  546. static short gExplainItem;
  547.  
  548. pascal void SetUpMenus(void)
  549. {
  550.     short             i;
  551.     StringHandle    str;
  552.  
  553.     myMenus[appleM] = GetMenu(appleID);
  554.     AddResMenu(myMenus[appleM], 'DRVR');
  555.     myMenus[fileM] = GetMenu(fileID);
  556.     myMenus[editM] = GetMenu(editID);
  557.     myMenus[windowM]    = GetMenu(windowID);
  558.     myMenus[perlM]    = GetMenu(perlID);
  559.     myMenus[editorM]    = GetMenu(editorID);
  560.     
  561.     if (gExternalEditor) {
  562.         Str63 name;
  563.         GetExternalEditorName(name);
  564.         Munger(
  565.             (Handle) myMenus[editorM], 14, 
  566.             nil, *myMenus[editorM][0]->menuData+1, 
  567.             (Ptr) name, *name+1);
  568.     }
  569.  
  570.     for (i = appleM; i < kLastMenu; i++)
  571.         if (i != editorM || gExternalEditor)
  572.             InsertMenu(myMenus[i], 0);
  573.  
  574.     HMGetHelpMenuHandle(&myMenus[helpM]);
  575.     str = GetString(helpID);
  576.     
  577.     HLock((Handle) str);
  578.     AppendMenu(myMenus[helpM], *str);
  579.     ReleaseResource((Handle) str);
  580.     
  581.     gExplainItem = CountMItems(myMenus[helpM]);
  582.  
  583.     AddStandardScripts();
  584.     
  585.     SetShortMenus(); /* Does a DrawMenuBar() */
  586. }
  587.  
  588. pascal void DoFile(short theItem)
  589. {
  590.     short   alertResult;
  591.     DPtr    theDoc;
  592.     FSSpec  theFSSpec;
  593.     OSErr   fileErr;
  594.     TPrint  thePSetup;
  595.  
  596.     switch (theItem){
  597.     case fmNew:
  598.         IssueAENewWindow();
  599.         break;
  600.  
  601.     case fmOpen:
  602.         if (GetFile(&theFSSpec)==noErr)
  603.             fileErr = IssueAEOpenDoc(theFSSpec);
  604.         break;
  605.  
  606.     case fmClose:
  607.         IssueCloseCommand(FrontWindow());
  608.         break;
  609.  
  610.     case fmSave:
  611.     case fmSaveAs:
  612.         theDoc = DPtrFromWindowPtr(FrontWindow());
  613.  
  614.         if (theItem==fmSaveAs || theDoc->kind != kDocumentWindow || !theDoc->u.reg.everSaved) {
  615.             fileErr = GetFileNameToSaveAs(theDoc);
  616.             if (!fileErr)
  617.                 fileErr = IssueSaveCommand(theDoc, &theDoc->theFSSpec);
  618.             else if (fileErr != userCanceledErr)    
  619.                 FileError((StringPtr) "\perror saving ", theDoc->theFileName);
  620.         } else
  621.             fileErr = IssueSaveCommand(theDoc, nil);
  622.         break;
  623.  
  624.     case fmRevert:
  625.         SetCursor(&qd.arrow);
  626.         theDoc = DPtrFromWindowPtr(FrontWindow());
  627.  
  628.         ParamText(theDoc->theFileName, (StringPtr) "", (StringPtr) "", (StringPtr) "");
  629.         alertResult = Alert(RevertAlert, nil);
  630.         switch (alertResult){
  631.             case aaSave:
  632.                 if (IssueRevertCommand(theDoc->theWindow))
  633.                     FileError((StringPtr) "\perror reverting ", theDoc->theFileName);
  634.         }
  635.         break;
  636.  
  637.     case fmPageSetUp:
  638.         theDoc = DPtrFromWindowPtr(FrontWindow());
  639.         if (DoPageSetup(theDoc)) {
  640.              thePSetup = **(theDoc->thePrintSetup);
  641.              IssuePageSetupWindow(theDoc->theWindow, thePSetup);
  642.          }
  643.         break;
  644.  
  645.     case fmPrint:
  646.         IssuePrintWindow(FrontWindow());
  647.          break;
  648.  
  649.     case fmQuit:
  650.         IssueQuitCommand();
  651.         break;
  652.     } /*of switch*/
  653. }
  654.  
  655. #if !defined(powerc) && !defined(__powerc)
  656. #pragma segment MPMain
  657. #endif
  658.  
  659. pascal void DoCommand(long mResult, Boolean option, Boolean mousing)
  660. {
  661.     short          theMenu;
  662.     short       theItem;
  663.     short       err;
  664.     Str255      name;
  665.     DPtr        theDocument;
  666.  
  667.     if (gFilterMenu && gFilterMenu(mResult))
  668.         return;
  669.  
  670.     if (!mResult) {
  671.         /*
  672.          * Hierarchical submenus of the Help menu are broken. We therefore
  673.          * special case for them but prevent this route from being taken for
  674.          * any other menu
  675.          */
  676.         
  677.         if (mousing)
  678.             mResult = MenuChoice();
  679.         
  680.         if (!mResult)
  681.             return;
  682.         else
  683.             mResult |= 0x80000000;
  684.     }
  685.     
  686.     theDocument = DPtrFromWindowPtr(FrontWindow());
  687.         
  688.     if (gTextServicesImplemented && TSMMenuSelect(mResult))
  689.         goto done;
  690.     if (theDocument && theDocument->tsmDoc)
  691.         FixTSMDocument(theDocument->tsmDoc);
  692.  
  693.     theItem = LoWord(mResult);
  694.  
  695.     switch (theMenu = HiWord(mResult)) {
  696.     case appleID:
  697.         if (theItem == aboutItem) {
  698.             DoAbout(option);
  699.         } else {
  700.             GetItem(myMenus[appleM], theItem, name);
  701.             err = OpenDeskAcc(name);
  702.             SetPort(FrontWindow());
  703.         }
  704.           break;
  705.  
  706.     case fileID:
  707.         DoFile(theItem);
  708.         break;
  709.  
  710.     case editID:
  711.         SystemEdit(theItem - 1);
  712.  
  713.         switch (theItem) {
  714.         case cutCommand:
  715.             IssueCutCommand(theDocument);
  716.             break;
  717.  
  718.         case copyCommand:
  719.             IssueCopyCommand(theDocument);
  720.             break;
  721.  
  722.         case pasteCommand :
  723.             IssuePasteCommand(theDocument);
  724.             break;
  725.  
  726.         case clearCommand :
  727.             IssueClearCommand(theDocument);
  728.             break;
  729.  
  730.         case selectAllCommand:
  731.             if (theDocument)
  732.                 TESetSelect(0, (**(theDocument->theText)).teLength, theDocument->theText);
  733.             break;
  734.  
  735. #ifdef EVIL_USELESS_EDITIONS
  736.         case cPublisher:
  737.             IssueCreatePublisher(theDocument);
  738.             break;
  739.  
  740.         case cSubscriber:
  741.             DoSubscribe(theDocument);
  742.             break;
  743.  
  744.         case cOptions:
  745.             DoSectionOptions(theDocument);
  746.             break;
  747.  
  748.         case cBorders:
  749.             IssueShowBorders(theDocument->theWindow, !theDocument->u.reg.showBorders);
  750.             break;
  751. #endif
  752.  
  753.         case emJumpTo:
  754.             IssueJumpCommand(&jumpFile, jumpWindow, jumpLine);
  755.             break;
  756.             
  757.         case emFormat:
  758.             IssueFormatCommand(theDocument);
  759.             break;
  760.             
  761.         case emPreferences:
  762.             DoPrefDialog();
  763.             break;
  764.         }     /*of switch*/
  765.  
  766.         ShowSelect(theDocument);
  767.          break;
  768.     
  769.     case windowID:
  770.         DoSelectWindow(theItem);
  771.         break;
  772.  
  773.     case editorID:
  774.         switch (theItem) {
  775.         case xmEdit:
  776.             StartExternalEditor(false);
  777.             break;
  778.         case xmEditFront:
  779.             StartExternalEditor(true);
  780.             break;
  781.         case xmUpdate:
  782.             UpdateExternalEditor(false);
  783.             break;
  784.         case xmUpdateFront:
  785.             UpdateExternalEditor(true);
  786.             break;
  787.         }
  788.         break;
  789.         
  790.     case perlID:
  791.         DoScriptMenu(theItem);
  792.         break;
  793.  
  794.     case kHMHelpMenuID:
  795.         if (theItem < gExplainItem)
  796.             break;
  797.         else if (theItem == gExplainItem)
  798.             Explain(theDocument);
  799.         else
  800.             DoHelp(0, theItem);
  801.         break;
  802.     
  803.     default:
  804.         theMenu &= 0x7FFF;
  805.         
  806.         if (theMenu > kHierHelpMenu && theMenu < kHierHelpMenu+20)
  807.             DoHelp(theMenu - kHierHelpMenu, theItem);
  808.         break;
  809.     }                 /*of switch*/
  810.  
  811. done:
  812.     HiliteMenu(0);
  813. }
  814.  
  815. #if !defined(powerc) && !defined(__powerc)
  816. #pragma segment MPMain
  817. #endif
  818.  
  819. pascal void DoMouseDown(EventRecord *myEvent)
  820. {
  821.     WindowPtr whichWindow;
  822.     Point     p;
  823.     Rect      dragRect;
  824.  
  825.     p = myEvent->where;
  826.     switch (FindWindow(p, &whichWindow)) {
  827.     case inDesk:
  828.         SysBeep(10);
  829.         break;
  830.  
  831.     case inGoAway:
  832.         if (Ours(whichWindow))
  833.             if (TrackGoAway(whichWindow, p))
  834.                 IssueCloseCommand(whichWindow);
  835.         break;
  836.  
  837.     case inMenuBar:
  838.         SetCursor(&qd.arrow);
  839.         SetupWindowMenu();
  840.         MaintainMenus();
  841.         if (gFilterMenu)
  842.             gFilterMenu(-1);
  843.         DoCommand(MenuSelect(p), (myEvent->modifiers & optionKey) == optionKey, true);
  844.         HiliteMenu(0);
  845.         break;
  846.  
  847.     case inSysWindow:
  848.         SystemClick(myEvent, whichWindow);
  849.         break;
  850.  
  851.     case inDrag:
  852.         dragRect = qd.screenBits.bounds;
  853.  
  854.         if (Ours(whichWindow)) {
  855.             DragWindow(whichWindow, p, &dragRect);
  856.             /*
  857.                 As rgnBBox may be passed by address
  858.             */
  859.             dragRect = (**((WindowPeek)whichWindow)->strucRgn).rgnBBox;
  860.             /*
  861.                 The windows already there, but still tell
  862.                 the our AppleEvents core about the move in case
  863.                 they want to do anything
  864.             */
  865.             IssueMoveWindow(whichWindow, dragRect);
  866.         }
  867.           break;
  868.  
  869.     case inGrow:
  870.         SetCursor(&qd.arrow);
  871.         if (Ours(whichWindow))
  872.             MyGrowWindow(whichWindow, p);
  873.         break;
  874.  
  875.     case inZoomIn:
  876.         DoZoom(whichWindow, inZoomIn, p);
  877.         break;
  878.  
  879.     case inZoomOut:
  880.         DoZoom(whichWindow, inZoomOut, p);
  881.         break;
  882.  
  883.     case inContent:
  884.         if (whichWindow != FrontWindow())
  885.             SelectWindow(whichWindow);
  886.         else
  887.             if (Ours(whichWindow))
  888.                 DoContent(whichWindow, myEvent);
  889.         break;
  890.     }                 /*of switch*/
  891. }
  892.  
  893. #if !defined(powerc) && !defined(__powerc)
  894. #pragma segment MPMain
  895. #endif
  896.  
  897. pascal long GetSleep(void)
  898. {
  899.     long      sleep;
  900.     WindowPtr theWindow;
  901.     DPtr      theDoc;
  902.  
  903.     sleep = 30;
  904.     if (!gInBackground)
  905.         {
  906.             theWindow = FrontWindow();
  907.             if (theWindow)
  908.                 {
  909.                     theDoc = DPtrFromWindowPtr(theWindow);
  910.                     if ((**(theDoc->theText)).selStart == (**(theDoc->theText)).selEnd)
  911.                         sleep = GetCaretTime();
  912.                 }
  913.         }
  914.     return(sleep);
  915. }                     /*GetSleep*/
  916.  
  917. long FindMenuKey(EventRecord * ev)
  918. {
  919.     /* Work around Help manager bug */
  920.     short    key;
  921.     
  922.     GetItemCmd(myMenus[helpM], gExplainItem, &key);
  923.     
  924.     if (toupper((char) key) == toupper(ev->message & charCodeMask))
  925.         return (kHMHelpMenuID << 16) | gExplainItem;
  926.     else {
  927.         MaintainMenus();
  928.  
  929.         return MDEF_MenuKey(ev->message, ev->modifiers, myMenus[fileM]);
  930.     }
  931. }
  932.  
  933. #if !defined(powerc) && !defined(__powerc)
  934. #pragma segment MPMain
  935. #endif
  936.  
  937. typedef enum {keyOK, keyRetry, keyAbort} KeyStatus;
  938.  
  939. #define kHome        1
  940. #define kEnd        4
  941. #define kHelp        5
  942. #define kPageUp    11
  943. #define kPageDown    12
  944.  
  945. KeyStatus TryKey(DPtr theDoc, char theChar)
  946. {
  947.     short value;
  948.     
  949.     if (theDoc->kind != kDocumentWindow && DoRawConsole(theDoc->u.cons.cookie, theChar))
  950.         return keyOK;
  951.  
  952.     switch (theChar) {
  953.     case 0:
  954.     case 2:
  955.     case 6:
  956.     case 7:
  957.     case 10:
  958.     case 14:
  959.     case 15:
  960.     case 16:
  961.     case 17:
  962.     case 18:
  963.     case 19:
  964.     case 20:
  965.     case 21:
  966.     case 22:
  967.     case 23:
  968.     case 24:
  969.     case 25:
  970.     case 26:
  971.     case 27:
  972.     case 0x7F:
  973.         return keyAbort;
  974.     case kHome:
  975.         value = GetCtlValue(theDoc->vScrollBar);
  976.         SetCtlValue(theDoc->vScrollBar, GetCtlMin(theDoc->vScrollBar));
  977.         DoThumb(theDoc, theDoc->vScrollBar, value);
  978.         
  979.         return keyOK;
  980.     case kEnd:
  981.         value = GetCtlValue(theDoc->vScrollBar);
  982.         SetCtlValue(theDoc->vScrollBar, GetCtlMax(theDoc->vScrollBar));
  983.         DoThumb(theDoc, theDoc->vScrollBar, value);
  984.         
  985.         return keyOK;
  986.     case kPageUp:
  987.         VActionProc(theDoc->vScrollBar, inPageUp);
  988.         return keyOK;
  989.     case kPageDown:
  990.         VActionProc(theDoc->vScrollBar, inPageDown);
  991.         return keyOK;
  992.     case kHelp:
  993.         Explain(theDoc);
  994.         return keyOK;
  995.     case ETX:
  996.         theChar = CR;
  997.         
  998.         break;
  999.     default:
  1000.         break;
  1001.     }
  1002.  
  1003. #ifdef EVIL_USELESS_EDITIONS
  1004.     {
  1005.         SectHandle  currSection;
  1006.         
  1007.         /*
  1008.             don't allow a subscriber to be changed
  1009.         */
  1010.         currSection =
  1011.             GetSection(
  1012.                 (**(theDoc->theText)).selStart,
  1013.                 (**(theDoc->theText)).selEnd,
  1014.                 theDoc);
  1015.     
  1016.         if (currSection)
  1017.             if ((**(**currSection).fSectHandle).kind == stSubscriber)
  1018.                 if (!KeyOKinSubscriber(theChar))
  1019.                     return keyAbort;
  1020.     }
  1021. #endif
  1022.  
  1023.     if (theDoc->kind == kDocumentWindow) {
  1024. #ifdef EVIL_USELESS_EDITIONS
  1025.         DoTEKeySectionRecalc(theDoc, theChar);
  1026. #endif
  1027.     } else if (theChar == BS) {
  1028.         if (AllSelected(theDoc->theText)) {
  1029.             if (theDoc->u.cons.fence < 32767)
  1030.                 theDoc->u.cons.fence = 0;
  1031.         } else if ((*theDoc->theText)->selStart == (*theDoc->theText)->selEnd)
  1032.             if ((*theDoc->theText)->selStart-1 < theDoc->u.cons.fence)
  1033.                 return keyAbort;
  1034.             else if ((*theDoc->theText)->selStart < theDoc->u.cons.fence)
  1035.                 return keyAbort;
  1036.     } else if (
  1037.         (*theDoc->theText)->selStart < theDoc->u.cons.fence &&
  1038.         !KeyOKinSubscriber(theChar)
  1039.     ) 
  1040.         return keyAbort;
  1041.     else if (!theDoc->u.cons.selected)
  1042.         return gRunningPerl ? keyRetry : keyAbort;
  1043.  
  1044.     AddKeyToTypingBuffer(theDoc, theChar);
  1045.     TEKey(theChar, theDoc->theText);
  1046.     EnforceMemory(theDoc, theDoc->theText);
  1047.     AdjustScrollbars(theDoc, false);
  1048.     ShowSelect(theDoc);
  1049.  
  1050.     theDoc->dirty = true;
  1051.     
  1052.     return keyOK;
  1053. }
  1054.  
  1055. #if !defined(powerc) && !defined(__powerc)
  1056. #pragma segment MPMain
  1057. #endif
  1058.  
  1059. static Boolean IntlTSMEvent(EventRecord *event)
  1060. {
  1061.     short oldFont;
  1062.     ScriptCode keyboardScript;
  1063.     
  1064.     if (qd.thePort != nil)
  1065.     {
  1066.         oldFont = qd.thePort->txFont;
  1067.         keyboardScript = GetScriptManagerVariable(smKeyScript);
  1068.         if (FontToScript(oldFont) != keyboardScript)
  1069.             TextFont(GetScriptVariable(keyboardScript, smScriptAppFond));
  1070.     };
  1071.     return TSMEvent(event);
  1072. }
  1073.  
  1074. /* Our cursor/WaitNextEvent strategy */
  1075.  
  1076. #define FRONT_BUSY_WAIT    120
  1077. #define BACK_BUSY_WAIT    30
  1078. #define FRONT_FREQUENCY    30
  1079. #define BACK_FREQUENCY  10
  1080.  
  1081. static long            lastNonBusy     = 0;
  1082. static long         lastWNE         = 0;
  1083. static long            lastBusySpin    = 0;
  1084. static char            deferredKeys[256];
  1085. static short        deferredRd        = 0;
  1086. static short        deferredWr        = 0;
  1087. static WindowPtr    deferredWindow    = 0;
  1088. static RgnHandle    mouseRgn;
  1089.  
  1090. #if !defined(powerc) && !defined(__powerc)
  1091. #pragma segment MPMain
  1092. #endif
  1093.  
  1094. void HandleEvent(EventRecord * myEvent)
  1095. {
  1096.     char        theChar;
  1097.     Boolean     activate;
  1098.     Point            mouse;
  1099.     WindowPtr   theWindow;
  1100.     DPtr        theDoc;
  1101.  
  1102.     if (gFilterEvent)
  1103.         gFilterEvent(myEvent);
  1104.         
  1105.     theDoc = DPtrFromWindowPtr(FrontWindow());
  1106.     
  1107.     switch (myEvent->what) {
  1108.     case mouseDown:
  1109.         FlushAndRecordTypingBuffer();
  1110.         DoMouseDown(myEvent);
  1111.         lastNonBusy = TickCount();
  1112.         break;
  1113.  
  1114.     case keyDown:
  1115.     case autoKey:
  1116.         if (WeirdChar(myEvent, cmdKey, ETX) 
  1117.          || WeirdChar(myEvent, controlKey, 'd')
  1118.         )    {
  1119.             if (theDoc && theDoc->kind != kDocumentWindow && !DoRawConsole(theDoc->u.cons.cookie, '\004')) {
  1120.                 gGotEof            =    theDoc;
  1121.                 theDoc->dirty     =     true;
  1122.             } 
  1123.             
  1124.             break;
  1125.         } 
  1126.         
  1127.         theChar = myEvent->message & charCodeMask;
  1128.  
  1129.         if ((myEvent->modifiers & cmdKey) == cmdKey) {
  1130.             FlushAndRecordTypingBuffer();
  1131.             if (gFilterMenu)
  1132.                 gFilterMenu(-1);
  1133.             DoCommand(FindMenuKey(myEvent), (myEvent->modifiers & optionKey) == optionKey, false);
  1134.             HiliteMenu(0);
  1135.         } else if (theDoc && theDoc->theText)
  1136.             switch (TryKey(theDoc, theChar)) {
  1137.             case keyOK:
  1138.             case keyAbort:
  1139.                 break;
  1140.             case keyRetry:
  1141.                 if (FrontWindow() != deferredWindow) {
  1142.                     deferredRd = deferredWr;
  1143.                     deferredWindow = FrontWindow();
  1144.                 }
  1145.                 deferredKeys[deferredWr] = theChar;
  1146.                 deferredWr = (deferredWr + 1) & 255;
  1147.                 break;
  1148.             }
  1149.         break;
  1150.  
  1151.     case activateEvt:
  1152.         activate = ((myEvent->modifiers & activeFlag) != 0);
  1153.         theWindow = (WindowPtr)myEvent->message;
  1154.         DoActivate(theWindow, activate);
  1155.         break;
  1156.  
  1157.     case updateEvt:
  1158.         theWindow = (WindowPtr)myEvent->message;
  1159.         DoUpdate(DPtrFromWindowPtr(theWindow), theWindow);
  1160.         break;
  1161.  
  1162.     case kHighLevelEvent:
  1163.         FlushAndRecordTypingBuffer();
  1164.         DoAppleEvent(*myEvent);
  1165.         
  1166.         if (gDelayedScript.dataHandle) {
  1167.             AppleEvent    awakenedScript = gDelayedScript;
  1168.             
  1169.             gDelayedScript.dataHandle = nil;
  1170.             
  1171.             DoScript(&awakenedScript, nil, 0);
  1172.             AEDisposeDesc(&awakenedScript);
  1173.         }
  1174.         break;
  1175.  
  1176.     case kOSEvent:
  1177.         switch (myEvent->message & osEvtMessageMask) { /*high byte of message*/
  1178.         case 0x01000000:
  1179.                 FlushAndRecordTypingBuffer();
  1180.                 gInBackground = ((myEvent->message & resumeFlag) == 0);
  1181.                 if (!gInBackground)
  1182.                     InitCursor();
  1183.                 DoActivate(FrontWindow(), !gInBackground);
  1184.         }
  1185.         break;
  1186.     case diskEvt:
  1187.         if (myEvent->message & 0xFFFF0000) {
  1188.             DILoad();
  1189.             SetPt(&mouse, 120, 120);
  1190.             DIBadMount(mouse, myEvent->message);
  1191.             DIUnload();
  1192.         }
  1193.     }
  1194. }
  1195.  
  1196. pascal void MainEvent(Boolean busy)
  1197. {
  1198.     DPtr        theDoc;
  1199.     Boolean        gotEvent;
  1200.     Boolean        spinning;
  1201.     WindowPtr   theWindow;
  1202.     long            now;
  1203.     EventRecord myEvent;
  1204.     Point            mouse;
  1205.  
  1206.     if (!gSacrificialGoat)        /* Memory trouble */
  1207.         if (gRunningPerl)            /* This script has gone too far */
  1208.             Perl_die("Out of memory ! Aborting script for your own good...\n");
  1209.         else                            /* We aborted it, now buy a new goat */
  1210.             if (!(gSacrificialGoat = NewHandle(SACRIFICE)))
  1211.                 exit(0);        /* Save our sorry ass. Shouldn't happen */
  1212.     
  1213.     now = LMGetTicks();
  1214.     if (spinning = busy) {
  1215.         if (now - lastNonBusy < (gInBackground ? BACK_BUSY_WAIT : FRONT_BUSY_WAIT))
  1216.             spinning = false;
  1217.     } else
  1218.         lastNonBusy = now;
  1219.     
  1220.     MaintainMenuBar();
  1221.  
  1222.     if (spinning) {
  1223.         if (now-lastBusySpin < 3) 
  1224.             return;
  1225.         
  1226.         lastBusySpin = now;
  1227.         SpinCursor(1);
  1228.         
  1229.         if (now - lastWNE < (gInBackground ? BACK_FREQUENCY : FRONT_FREQUENCY))
  1230.             return;
  1231.     } else
  1232.         MaintainCursor();
  1233.     
  1234.     lastWNE = now;    
  1235.     gGotEof = nil;
  1236.     
  1237.     if (!gRunningPerl && GetHandleSize((Handle) gWaitingScripts)) {
  1238.         AppleEvent ev    =    (*gWaitingScripts)[0];
  1239.         AppleEvent repl    =    (*gWaitingScripts)[1];
  1240.         
  1241.         Munger((Handle) gWaitingScripts, 0, nil, 16, (Ptr) -1, 0);
  1242.         
  1243.         AESetTheCurrentEvent(&ev);
  1244.         DoScript(&ev, &repl, 0);
  1245.         AEResumeTheCurrentEvent(
  1246.             &ev, &repl, (AEEventHandlerUPP) kAENoDispatch, -1);
  1247.     }
  1248.     
  1249.     if ((theDoc = DPtrFromWindowPtr(FrontWindow())) && theDoc->theText) 
  1250.         while (deferredKeys[deferredRd]) {
  1251.             switch (deferredWindow != FrontWindow() ? keyAbort : TryKey(theDoc, deferredKeys[deferredRd])) {
  1252.             case keyOK:
  1253.             case keyAbort:
  1254.                 deferredKeys[deferredRd] = 0;
  1255.                 deferredRd = (deferredRd + 1) & 255;
  1256.                 continue;
  1257.             }
  1258.             break;
  1259.         }
  1260.  
  1261.     if (!(theWindow = FrontWindow()))
  1262.         GetWMgrPort(&theWindow);
  1263.         
  1264.     SetPort(theWindow);
  1265.  
  1266.     SetScriptManagerVariable(smFontForce, gSavedFontForce);
  1267.  
  1268.     if (!busy) {
  1269.         if (!mouseRgn) 
  1270.             mouseRgn    =    NewRgn();
  1271.         
  1272.         GetMouse(&mouse);
  1273.         SetRectRgn(mouseRgn, mouse.h, mouse.v, mouse.h, mouse.v);
  1274.         gotEvent = WaitNextEvent(everyEvent, &myEvent, GetSleep(), mouseRgn);
  1275.     } else 
  1276.         gotEvent = WaitNextEvent(everyEvent, &myEvent, 0, nil);
  1277.  
  1278.     // clear fontForce again so it doesn't upset our operations
  1279.     gSavedFontForce = GetScriptManagerVariable(smFontForce);
  1280.     (void) SetScriptManagerVariable(smFontForce, 0);
  1281.         
  1282.     if (gotEvent && gTextServicesImplemented && IntlTSMEvent(&myEvent))
  1283.         gotEvent = false;        // TSMTE handled it without our help
  1284.  
  1285.     if (gotEvent)
  1286.         HandleEvent(&myEvent);
  1287.         
  1288.     if (gQuitting && gRunningPerl)
  1289.         Perl_my_exit(-128);
  1290. }
  1291.  
  1292. pascal long VoodooChile(Size cbNeeded)
  1293. {
  1294. #if !defined(powerc) && !defined(__powerc)
  1295.     long    oldA5 = SetCurrentA5();
  1296. #endif
  1297.     long    res;
  1298.     
  1299.     if (gSacrificialGoat && (GZSaveHnd() != gSacrificialGoat)) {
  1300.         /* Oh Memory Manager, our dark Lord. Take the blood of this animal to
  1301.            unwield thy power to crush our enemies.
  1302.             
  1303.             (Chant 7 times)
  1304.         */
  1305.         DisposeHandle(gSacrificialGoat);
  1306.         
  1307.         gSacrificialGoat     =     0;
  1308.         res                    =    SACRIFICE;
  1309.     } else
  1310.         res                     =    0;
  1311.         
  1312. #if !defined(powerc) && !defined(__powerc)
  1313.     SetA5(oldA5);
  1314. #endif
  1315.     
  1316.     return res;
  1317. }
  1318.  
  1319.  
  1320. #if USESROUTINEDESCRIPTORS
  1321. RoutineDescriptor    uVoodooChile = 
  1322.         BUILD_ROUTINE_DESCRIPTOR(uppGrowZoneProcInfo, VoodooChile);
  1323. #else
  1324. #define uVoodooChile *(GrowZoneUPP)&VoodooChile
  1325. #endif
  1326.  
  1327. #if !defined(powerc) && !defined(__powerc)
  1328. #pragma segment MPMain
  1329. #endif
  1330.  
  1331. double * cs;
  1332. double * ps;
  1333.  
  1334. void main()
  1335. {
  1336.     OSErr  err;
  1337.     short  result;
  1338.  
  1339.     InitGraf(&qd.thePort);
  1340.     InitFonts();
  1341.     FlushEvents(everyEvent, 0);
  1342.     InitWindows();
  1343.     InitMenus();
  1344.     TEInit();
  1345.     InitDialogs(nil);
  1346.     InitCursor();
  1347.  
  1348.     SetApplLimit(GetApplLimit() - 65535);    /* We need more stack */
  1349.     MaxApplZone();
  1350.     SetGrowZone(&uVoodooChile);
  1351.     SetUpCursors();
  1352.  
  1353.     /* There appears to be a bug in current versions of Macintosh Easy Open that causes
  1354.         spurious System Error 28 crashes. The only remedy at the moment is to disable the
  1355.         stack sniffer 
  1356.     */
  1357. #define StackLowPoint (*(Ptr *)0x110)
  1358.     StackLowPoint = nil;
  1359.     
  1360.     /*check environment checks to see if we are running 7.0*/
  1361.     if (!CheckEnvironment()) {
  1362.         SetCursor(&qd.arrow);
  1363.         /*pose the only 7.0 alert*/
  1364.         result = Alert(302, nil);
  1365.         return;
  1366.     }
  1367.  
  1368.     gAppFile                = CurResFile();
  1369.  
  1370.     ICStart(&gICInstance, MPAppSig);
  1371.     if (gICInstance)
  1372.         ICFindConfigFile(gICInstance, 0, nil);
  1373.     
  1374.     gPerlPrefs.version             =     PerlPrefVersion500;
  1375.     gPerlPrefs.runFinderOpens    =    false;
  1376.     gPerlPrefs.checkType            =    false;
  1377.     gPerlPrefs.inlineInput        =     true;
  1378.     
  1379.     OpenPreferences();
  1380.     if (gPrefsFile)
  1381.         CloseResFile(gPrefsFile);
  1382.     UseResFile(gAppFile);
  1383.  
  1384.     InitExternalEditor();
  1385.     
  1386.     SetUpMenus();
  1387.  
  1388.     gWCount                = 0;
  1389.     gNewDocCount         = 0;
  1390.     gQuitting              = false;
  1391.     gWarnings              = false;
  1392.     gDebug                  = false;
  1393.     gFontMItem             = 0;
  1394.     gConsoleList        = nil;
  1395.     gActiveWindow        = nil;
  1396.     gScriptFile            = gAppFile;
  1397.     gWaitingScripts    = (AppleEvent **) NewHandle(0);
  1398.     gGotEof                = nil;
  1399.     gSacrificialGoat    = NewHandle(SACRIFICE);
  1400.     gPerlPool            = new_malloc_pool('PERL', SUGGESTED_BLK_SIZE);
  1401.  
  1402.     setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
  1403.  
  1404. #ifdef EVIL_USELESS_EDITIONS
  1405.     if (err = InitEditionPack()) {
  1406.         ShowError((StringPtr) "\pInitEditionPack", err);
  1407.         gQuitting = true;
  1408.     }
  1409. #endif
  1410.  
  1411.     if (err = AEObjectInit()) {
  1412.         ShowError((StringPtr) "\pAEObjectInit", err);
  1413.         gQuitting = true;
  1414.     }
  1415.  
  1416.     InitAppleEvents();
  1417.  
  1418.     if (err = PPCInit()) {
  1419.         ShowError((StringPtr) "\pPPCInit", err);
  1420.         gQuitting = true;
  1421.     }
  1422.  
  1423.     if (!(gTSMTEImplemented && !InitTSMAwareApplication())) {
  1424.         gTextServicesImplemented = false;
  1425.         gTSMTEImplemented = false;
  1426.     }
  1427.     
  1428.     InitConsole();
  1429.     InitPseudo();
  1430.     InitHelp();
  1431.     InitHelpIndex();
  1432.     EndHelp();
  1433.  
  1434.     gSavedFontForce = GetScriptManagerVariable(smFontForce);
  1435.     (void) SetScriptManagerVariable(smFontForce, 0);
  1436.     
  1437.     if (gQuitting)
  1438.         exit(0);
  1439.         
  1440.     InitPerlEnviron();
  1441.     
  1442.     GUSISetSpin(MPConsoleSpin);
  1443.     
  1444.     for (gQuitting = DoRuntime(); !gQuitting; )
  1445.         MainEvent(false);
  1446.  
  1447.     if (gICInstance)
  1448.         ICStop(gICInstance);
  1449.         
  1450.     if (gTextServicesImplemented)
  1451.         CloseTSMAwareApplication();
  1452.     SetScriptManagerVariable(smFontForce, gSavedFontForce);
  1453.     
  1454.     ExitToShell();
  1455. }
  1456.